package controller

import (
	"cloud-storage/global"
	"cloud-storage/lib"
	"cloud-storage/model/mysql"
	"cloud-storage/utils/response"
	"cloud-storage/utils/upload"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net/http"
	"strconv"
)

// Files 全部文件页面
func Files(c *gin.Context) {
	phone := global.GetPhone(c)
	fId := c.DefaultQuery("fId", "0")
	//获取用户信息
	user, err := mysql.GetUserInfo(phone)
	if err != nil {
		zap.L().Error("mysql.GetUserInfo() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}
	//获取当前目录的所有文件
	files, err := mysql.GetUserFile(fId, user.FileStoreId)
	if err != nil {
		zap.L().Error("mysql.GetUserFile() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}
	//获取父级的文件夹信息
	parentFolder, err := mysql.GetParentFolder(fId)
	if err != nil {
		zap.L().Error("mysql.GetParentFolder() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}
	//获取当前目录的所有文件夹
	fileFolder, err := mysql.GetFileFolder(fId, user.FileStoreId)
	if err != nil {
		zap.L().Error("mysql.GetFileFolder() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}
	//获取当前目录信息
	currentFolder, err := mysql.GetCurrentFolder(fId)
	if err != nil {
		zap.L().Error("mysql.GetCurrentFolder() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}

	//获取当前目录所有父级
	currentAllParent := mysql.GetCurrentAllParent(parentFolder, make([]mysql.FileFolder, 0))

	//获取用户文件使用明细数量
	fileDetailUse := mysql.GetFileDetailUser(user.FileStoreId)

	response.ResponseSuccess(c, gin.H{
		"currAll":          "active",
		"user":             user,
		"fId":              currentFolder.Id,
		"fName":            currentFolder.FileFolderName,
		"files":            files,
		"fileFolder":       fileFolder,
		"parentFolder":     parentFolder,
		"currentAllParent": currentAllParent,
		"fileDetailUse":    fileDetailUse,
	})

}

// AddFolder 新建文件夹
func AddFolder(c *gin.Context) {
	phone := global.GetPhone(c)
	user, err := mysql.GetUserInfo(phone)
	if err != nil {
		zap.L().Error("mysql.GetUserInfo() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}
	folderName := c.PostForm("fileFolderName")
	parentId := c.DefaultPostForm("parentFolderId", "0")
	//判断该目录下是否已经有该文件
	if ok := mysql.FolderIsExist(folderName, parentId); ok {
		//新建文件夹
		err = mysql.CreateFolder(folderName, parentId, user.FileStoreId)
		if err != nil {
			zap.L().Error("mysql.CreateFolde() failed err:", zap.Error(err))
			response.ResponseError(c, response.CodeInsertOperationFail)
			return
		}
		c.Redirect(http.StatusMovedPermanently, "/api/v1/files?fId="+parentId)
	} else {
		response.ResponseErrorWithMsg(c, response.CodeError, "文件夹已存在")
		return
	}
}

// DownloadFile 从oss下载文件
func DownloadFile(c *gin.Context) {
	fId := c.Query("fId")
	//通过文件id获取文件
	file, err := mysql.GetFileInfo(fId)
	if err != nil {
		zap.L().Error(" mysql.GetFileInfo() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}
	//从oss上获取文件
	fileData, err := upload.DownloadOss(file.FileHash, file.Postfix)
	if err != nil {
		response.ResponseErrorWithMsg(c, response.CodeError, "下载失败")
		return
	}
	//下载次数加1
	err = mysql.DownloadNumAdd(fId)
	if err != nil {
		zap.L().Error(" mysql.DownloadNumAdd() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeOperationFail)
		return
	}
	//设置下载文件的文件名
	c.Header("Content-disposition", "filename=\""+file.FileName+file.Postfix+"\"")
	//将数据加入到下载的文件中，否则下载的文件就没有数据
	c.Data(http.StatusOK, "application/octect-stream", fileData)
}

// DeleteFileOss 删除oss上的文件
func DeleteFileOss(c *gin.Context) {
	fId := c.Query("fId")
	//通过文件id获取文件
	file, err := mysql.GetFileInfo(fId)
	if err != nil {
		zap.L().Error(" mysql.GetFileInfo() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}
	key := lib.OssSetting.BasePath + file.FileHash + file.Postfix
	err = upload.DeleteFile(key)
	if err != nil {
		response.ResponseError(c, response.CodeOperationFail)
		return
	}
	//删除数据库中的该文件
	err = mysql.DeleteFileOss(fId)
	if err != nil {
		zap.L().Error("mysql.DeleteFileOss() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeDeleteOperationFail)
	}
	folderId := strconv.Itoa(file.ParentFolderId)
	fmt.Println(folderId)
	c.Redirect(http.StatusMovedPermanently, "/api/v1/files?fId="+folderId)
}

// UpdateFileFolder 修改文件夹名
func UpdateFileFolder(c *gin.Context) {
	fileFolderName := c.PostForm("fileFolderName")
	fileFolderId := c.PostForm("fileFolderId")
	fileFolder, err := mysql.GetCurrentFolder(fileFolderId)
	if err != nil {
		zap.L().Error("mysql.GetCurrentFolder() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}
	err = mysql.UpdateFolderName(fileFolderId, fileFolderName)
	if err != nil {
		zap.L().Error("mysql.UpdateFolderName() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeUpdateOperationFail)
		return
	}
	c.Redirect(http.StatusMovedPermanently, "/api/v1/files?fId="+strconv.Itoa(fileFolder.ParentFolderId))
}

// DeleteFileFolder 删除文件夹
func DeleteFileFolder(c *gin.Context) {
	fId := c.DefaultQuery("fId", "")
	//获取要删除的文件夹信息
	folderInfo, err := mysql.GetCurrentFolder(fId)
	if err != nil {
		zap.L().Error("mysql.GetCurrentFolder() failed err:", zap.Error(err))
		response.ResponseError(c, response.CodeSelectOperationFail)
		return
	}
	mysql.DeleteFileFolder(fId)
	c.Redirect(http.StatusMovedPermanently, "/api/v1/files?fId="+strconv.Itoa(folderInfo.ParentFolderId))
}
